package com.softserveinc.moviedbapp.fragment;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.ActionBar;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.ListFragment;
import android.support.v4.app.SupportActivity;
import android.util.Log;
import android.view.View;
import android.widget.ListView;

import com.softserveinc.moviedbapp.R;
import com.softserveinc.moviedbapp.adapter.MovieAdapter;
import com.softserveinc.moviedbapp.application.MovieDBApplication;
import com.softserveinc.moviedbapp.manager.DataManager;
import com.softserveinc.moviedbapp.model.Movie;

import java.util.ArrayList;
import java.util.List;

public class MovieItemsFragment extends ListFragment {

	private MovieAdapter mMovieAdapter;
	private ActionBar mActionBar;
	private View mProgressBar;
	private String mSearchQuery;

	private boolean mForceRefresh;
	private boolean mNeedGetPosters = true;

	private int mPosterCount;
	private int mCurrentPosition;

	private OnMovieSelectedListener mListener;
	private static String TAG = MovieItemsFragment.class.getSimpleName();
	private DataManager mDataMananger;

	/* a callback interface that notifies movie info fragment about the event in this fragment */
	public interface OnMovieSelectedListener {
		public void onMovieSelected(Movie movie);
	}

	/* ensuring that the host activity implements the OnMovieSelectedListener interface */
	@Override
	public void onAttach(final SupportActivity activity) {
		Log.i(TAG, "onAttach()");
		super.onAttach(activity);
		try {
			mListener = (OnMovieSelectedListener) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
		}
	}

	@Override
	public void onActivityCreated(final Bundle savedInstanceState) {
		Log.i(TAG, "onActivityCreated()");
		if (savedInstanceState != null && !savedInstanceState.isEmpty()) {
			mSearchQuery = savedInstanceState.getString("search_query");
		}

		Log.i(TAG, "onActivityCreated()  search query " + mSearchQuery);
		super.onActivityCreated(savedInstanceState);

		/* get the reference to the action bar from the main fragment */
		mActionBar = ((FragmentActivity) getActivity()).getSupportActionBar();
		mProgressBar = mActionBar.getCustomView().findViewById(R.id.progressBar);

		/* set-up the movie adapter */
		mMovieAdapter = new MovieAdapter(getActivity(), R.layout.list_row, new ArrayList<Movie>());
		setListAdapter(mMovieAdapter);

		MovieDBApplication app = (MovieDBApplication) getActivity().getApplication();

		mDataMananger = app.getDataManager();

		mDataMananger.setMovieItems(new IFragmentCallback() {

			@Override
			/* show progress text and progress icon on the action bar */
			public void onGettingMovieList() {
				mProgressBar.setVisibility(View.VISIBLE);
			}

			@Override
			/* add movies to the Adapter */
			public void onMovieListRetrieved(final List<Movie> movies) {
				Log.i(TAG, "inside onMovieListRetrieved(final List<Movie> movies)");

				Log.i(TAG, movies.toString());
				List<String> posterUrls = new ArrayList<String>();
				mMovieAdapter.clear();
				for (Movie movie : movies) {
					mMovieAdapter.add(movie);
					posterUrls.add(movie.getThumbPosterUrl());
				}
				mPosterCount = posterUrls.size();
				if (movies.get(0).getPosterBitmap() != null) {
					mNeedGetPosters = false;
				}
				if (mNeedGetPosters) {
					mDataMananger.provideMoviePosters(posterUrls);
				} else {
					/* hide the progress icon on the action bar */
					mActionBar.getCustomView().findViewById(R.id.progressBar).setVisibility(View.INVISIBLE);
				}
			}

			@Override
			public void onMovieListRetrievalFailed() {
				AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
				/* if getting movie list failed re-try or exit */
				builder.setMessage(R.string.want_retry).setCancelable(false)
						.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
							@Override
							public void onClick(final DialogInterface dialog, final int id) {
								mDataMananger.provideMovieList(mSearchQuery);
							}
						}).setNegativeButton("No", new DialogInterface.OnClickListener() {
							@Override
							public void onClick(final DialogInterface dialog, final int id) {
								getActivity().finish();
							}
						});
				AlertDialog alert = builder.create();
				alert.show();
			}

			@Override
			public void onMoviePosterRetreived(final Bitmap poster) {
				Log.i(TAG, "inside onMoviePosterRetreived(final Bitmap poster)");
				mMovieAdapter.getItem(mCurrentPosition).setPosterBitmap(poster);
				mMovieAdapter.notifyDataSetChanged();
				mCurrentPosition++;
				if (mPosterCount == mCurrentPosition) {
					/* hide the progress icon on the action bar */
					mActionBar.getCustomView().findViewById(R.id.progressBar).setVisibility(View.INVISIBLE);
				}
			}
		});

		if (mForceRefresh == false) {
			/* get movies from cache or download them if needed */
			mDataMananger.provideMovieList(mSearchQuery);
		} else {
			/* refresh the movie list */
			mDataMananger.provideRefreshedMovieList();
			mForceRefresh = false;
		}
	}

	@Override
	public void onSaveInstanceState(final Bundle outState) {
		super.onSaveInstanceState(outState);
		Log.d(TAG, "in onSaveInstanceState() mSearchQuery = " + mSearchQuery);
		outState.putString("search_query", mSearchQuery);
	}

	@Override
	public void onPause() {
		mDataMananger.cancelMovieListFetching();
		mDataMananger.cancelPosterDownloading();
		Log.d(TAG, "onPause() called gonna cancelMovieListFetching() & cancelPosterDownloading()");
		super.onPause();
	}

	/* on list item click trigger the listener and pass it the movie */
	@Override
	public void onListItemClick(final ListView l, final View v, final int position, final long id) {
		Movie movie = mMovieAdapter.getItem(position);
		/* if user trys to click on a null search result do nothing */
		if (!movie.getName().equals("Nothing found.")) {
			mListener.onMovieSelected(movie);
		}
	}

	public void setSearchQuery(final String mSearchQuery) {
		this.mSearchQuery = mSearchQuery;
	}

	public void setForceRefresh(final boolean mForceRefresh) {
		this.mForceRefresh = mForceRefresh;
	}

}
